/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */
package com.yami.shop.distribution.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.distribution.common.constants.DistributionUserStateEnum;
import com.yami.shop.distribution.common.dao.DistributionUserBindMapper;
import com.yami.shop.distribution.common.dto.BindUserInfoDto;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.model.DistributionUserBind;
import com.yami.shop.distribution.common.service.DistributionBindUserService;
import com.yami.shop.distribution.common.service.DistributionUserService;
import com.yami.shop.distribution.common.vo.DistributionConfigVO;
import com.yami.shop.service.SysConfigService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Objects;

/**
 * @author yami
 */
@Slf4j
@Service
@AllArgsConstructor
public class DistributionBindUserServiceImpl implements DistributionBindUserService {

    private final DistributionUserService distributionUserService;

    private final SysConfigService sysConfigService;

    private final DistributionUserBindMapper distributionUserBindMapper;



    @Override
    public ServerResponseEntity bindDistribution(DistributionUser shareUser, String userId, int type) {
        //分享员信息
        if (shareUser == null) {
            // 获取推广员信息失败
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.distribution.get.fail"));
        }
        if (shareUser.getState() != 1) {
            log.info("推广员状态异常");
            // 推广员状态异常
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.distribution.status.error"));
        }
        DistributionConfigVO distributionConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_CONFIG, DistributionConfigVO.class);

        // 查询该用户以前绑定的分享人
        DistributionUserBind distributionUserBind = distributionUserBindMapper.selectOne(new LambdaQueryWrapper<DistributionUserBind>()
                .eq(DistributionUserBind::getShopId, Constant.PLATFORM_SHOP_ID)
                .eq(DistributionUserBind::getState, 1)
                .eq(DistributionUserBind::getUserId, userId)
        );

        // 没有绑定分享人，或分享人已被冻结，可以与该用户进行绑定
        if (distributionUserBind == null) {
            bindUser(userId, shareUser);
            return ServerResponseEntity.success(shareUser);
        }

        // 如果现在的分享人就是以前的分享人
        if (Objects.equals(distributionUserBind.getDistributionUserId(),shareUser.getDistributionUserId())) {
            // 如果绑定人相同 延长绑定时间
            updateBindTime(distributionUserBind.getBindId());
            return ServerResponseEntity.success(shareUser);
        }

        // 查询以前的绑定的用户信息
        DistributionUser oldDistributionUser = distributionUserService.getById(distributionUserBind.getDistributionUserId());

        // 不绑定，分享人优先
        if (Objects.equals(distributionConfigVO.getAttribution(), 1)) {
            unBindUser(distributionUserBind.getBindId());
            bindUser(userId, shareUser);
            return ServerResponseEntity.success(shareUser);
        }
        log.info("用户在保护期内，绑定失败");
        // 用户在保护期内，绑定失败
        return ServerResponseEntity.fail("200", I18nMessage.getMessage("yami.distribution.user.protection.period"), oldDistributionUser);
    }

    @Override
    public IPage<BindUserInfoDto> bindUserList(Page page, Long shopId, String userId) {
        return distributionUserBindMapper.bindUserList(page,shopId,userId);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void bindUser(Long shareDistributionId, Long distributionId) {
        if (shareDistributionId == null){
            log.info("没有分销员邀请，不改变绑定关系");
            return;
        }
        DistributionUser shareUser = distributionUserService.getById(shareDistributionId);
        DistributionUser user = distributionUserService.getById(distributionId);
        DistributionUserBind distributionUserBind = distributionUserBindMapper.selectOne(new LambdaQueryWrapper<DistributionUserBind>().eq(DistributionUserBind::getUserId, user.getUserId())
                .and(i -> i.eq(DistributionUserBind::getState, DistributionUserStateEnum.NORMAL.getValue())));
        if (distributionUserBind != null && StringUtils.isNotBlank(distributionUserBind.getUserId())){
            log.info("修改用户原有绑定关系");
            // 有绑定记录修改绑定状态
            distributionUserBind.setInvalidTime(new Date());
            distributionUserBind.setUpdateTime(new Date());
            distributionUserBind.setInvalidReason(1);
            distributionUserBind.setState(-1);
            distributionUserBindMapper.updateById(distributionUserBind);
        }
        bindUser(user.getUserId(), shareUser);
    }

    private void bindUser(String userId, DistributionUser sharerUser) {
        DistributionUserBind distributionUserBind = new DistributionUserBind();
        distributionUserBind.setBindTime(new Date());
        distributionUserBind.setUserId(userId);
        distributionUserBind.setState(1);
        distributionUserBind.setShopId(sharerUser.getShopId());
        distributionUserBind.setUpdateTime(new Date());
        distributionUserBind.setDistributionUserId(sharerUser.getDistributionUserId());
        distributionUserBindMapper.insert(distributionUserBind);
    }

    private void updateBindTime(Long bindId) {
        DistributionUserBind distributionUserBind = new DistributionUserBind();
        distributionUserBind.setBindId(bindId);
        distributionUserBind.setUpdateTime(new Date());
        distributionUserBindMapper.updateById(distributionUserBind);
    }

    private void unBindUser(Long bindId) {
        Date date = new Date();
        DistributionUserBind distributionUserBind = new DistributionUserBind();
        distributionUserBind.setBindId(bindId);
        distributionUserBind.setUpdateTime(date);
        distributionUserBind.setInvalidReason(2);
        distributionUserBind.setState(-1);
        distributionUserBind.setInvalidTime(date);
        distributionUserBindMapper.updateById(distributionUserBind);
    }
}
